抓包分析RST报文

您所在的位置:网站首页 powershell 过滤tcp rst报文 抓包分析RST报文

抓包分析RST报文

2024-07-16 03:51| 来源: 网络整理| 查看: 265

大家好,我是蓝胖子,今天我们来分析下网络连接中经常出现的RST信号,连接中出现RST信号意味着这条链接将会断开,来看下什么时候会触发RST信号,这在分析连接断开的原因时十分有帮助。

本文的讲解视频已经上传 抓包分析RST报文

在开始分析触发RST的场景之前,我们先来准备下需要的客户端和服务端代码,以方便我们进行测试。

服务端代码目前先是在8080端口监听,然后将接收到的消息打印出来。

func main() { listen, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } go func() { for { conn, err := listen.Accept() if err != nil { log.Fatal(err) } buf := make([]byte, 1024) n, err := conn.Read(buf) if err != nil { log.Fatal(err) } fmt.Println(string(buf[:n])) }() ch := make(chan int) xiongchongdembp.http-alt: Flags [S], seq 1854765658, win 65535, options [mss 16344,nop,wscale 6,nop,nop,TS val 98239951 ecr 0,sackOK,eol], length 0 18:58:14.745699 IP xiongchongdembp.http-alt > xiongchongdembp.63558: Flags [R.], seq 0, ack 1854765659, win 0, length 0

从tcpdump的抓包结果可以看出,客户端程序发出了握手信号[S],直接被回复了[R.]RST信号,可见,服务端没有监听端口时,系统内核会对想要连接该端口的客户端回复RST信号。

一端关闭了连接,另一端还在发送数据

再来看看客户端关闭后,对端继续发送消息的场景,这样的场景分为两种情况,一种事服务端发送keepalive消息,一种是服务端发送业务字节数据。

客户端关闭,服务端发送keepalive

先来看看发送keepalive消息的场景,这次同样用tcpdump监听8080端口,不过为了更清晰的分析这次抓包文件,我将tcpdump的抓包文件存到了本地,之后wireshark再去打开,tcpdump抓包命名如下:

sudo tcpdump -i lo0 port 8080 -w lo.pcap

接着,用文章开头准备的代码段启动服务端,客户端,注意,此时服务端仅仅是打印了收到的消息,并没有对客户端进行回应,而客户端进程也是在发送消息后就被销毁了。来看看此时的抓包文件

当客户端进程关闭时,即使没有显示的调用close方法,内核也会帮助我们关闭连接,发送fin信号,此时客户端连接会进入fin wait1状态,在这个状态下,客户端还是可以正常回应keep alive消息,不过超过fin wait1状态的超时时间时,则会被系统内核自动回收掉,此时再发送keepalive消息就会回复RST 这个超时时间在linux内核上可以通过下面这个文件进行修改,默认是1min。

root@ecs-295280:~# cat /proc/sys/net/ipv4/tcp_fin_timeout 60 客户端关闭,服务端发送消息

接着来看下,服务端在客户端关闭(无论是主动调用close方法还是进程结束连接被内核关闭都一样)的场景下主动发送消息触发RST的场景。

此时需要修改下目前服务端的代码了。

func main() { listen, err := net.Listen("tcp", ":8080") if err != nil { log.Fatal(err) } go func() { for { conn, err := listen.Accept() if err != nil { log.Fatal(err) } buf := make([]byte, 1024) n, err := conn.Read(buf) if err != nil { log.Fatal(err) } fmt.Println(string(buf[:n])) time.Sleep(time.Second) _, err = conn.Write([]byte("receive msg")) if err != nil { fmt.Println(err) } }() ch := make(chan int)


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3